package com.littcore.saap.message.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;

import com.littcore.saap.core.common.SaapConstants;
import com.littcore.saap.core.common.SaapConstants.CacheName;
import com.littcore.saap.core.module.message.meta.MessageMeta;
import com.littcore.saap.core.module.message.meta.MessageMetaManager;
import com.littcore.saap.core.module.message.meta.MessageModule;
import com.littcore.saap.message.dao.UserMessageSubDao;
import com.littcore.saap.message.po.UserMessageSub;
import com.littcore.saap.message.service.IUserMessageSubService;
import com.littcore.saap.message.vo.UserMessageSubVo;
import com.littcore.util.ArrayUtils;
import com.littcore.util.BeanCopier;
import com.littcore.util.StringUtils;


/**
 * .
 * 
 * <pre><b>描述：</b>
 *    
 * </pre>
 * 
 * <pre><b>修改记录：</b>
 *    
 * </pre>
 * 
 * @author <a href="mailto:littcai@hotmail.com">蔡源</a>
 * @since 2015年11月13日
 * @version 1.0
 */
public class UserMessageSubServiceImpl implements IUserMessageSubService {
    
  @Resource
  private UserMessageSubDao userMessageSubDao;
  
  /* (non-Javadoc)
   * @see com.littcore.saap.message.service.impl.IUserMessageSubService#saveOrUpdate(int, int, java.lang.String, java.lang.String, java.lang.String[])
   */
  @Override
  @CachePut(value=CacheName.USER_MESSAGE_SUB, key="#userId+'-'+#tenantId+'-'+#moduleCode+'-'+#messageCode")
  public UserMessageSubVo saveOrUpdate(int userId, int tenantId, String moduleCode, String messageCode, String[] channels)
  {
    UserMessageSub userMessageSub = this.load(userId, tenantId, moduleCode, messageCode);
    if(userMessageSub==null)
    {
      userMessageSub = new UserMessageSub();
      userMessageSub.setTenantId(tenantId);
      userMessageSub.setModuleCode(moduleCode);
      userMessageSub.setMessageCode(messageCode);
      userMessageSub.setChannels(Arrays.toString(channels));
      userMessageSub.setCreateBy(userId);
      userMessageSub.setCreateDatetime(new Date());
      userMessageSubDao.save(userMessageSub);
    }    
    else {
      userMessageSub.setChannels(Arrays.toString(channels));
      userMessageSubDao.update(userMessageSub);
    }
    UserMessageSubVo vo = BeanCopier.copy(userMessageSub, UserMessageSubVo.class);
    return vo;
  }  
  
  @CachePut(value=CacheName.USER_MESSAGE_SUB, key="#userId+'-'+#tenantId+'-'+#moduleCode+'-'+#messageCode")
  public UserMessageSubVo saveOrUpdate(int userId, int tenantId, String moduleCode, String messageCode, String channel)
  {
    UserMessageSub userMessageSub = this.load(userId, tenantId, moduleCode, messageCode);
    if(userMessageSub==null)
    {
      userMessageSub = new UserMessageSub();
      userMessageSub.setTenantId(tenantId);
      userMessageSub.setModuleCode(moduleCode);
      userMessageSub.setMessageCode(messageCode);
      userMessageSub.setChannels(channel);
      userMessageSub.setCreateBy(userId);
      userMessageSub.setCreateDatetime(new Date());
      userMessageSubDao.save(userMessageSub);
    }    
    else {
      String[] channels = StringUtils.split(userMessageSub.getChannels(), ",");
      if(!ArrayUtils.contains(channels, channel))
      {
        channels = (String[])ArrayUtils.add(channels, channel);
      }
      else {
        channels = (String[])ArrayUtils.removeElement(channels, channel);        
      }
      userMessageSub.setChannels(StringUtils.join(channels, ','));
      userMessageSubDao.update(userMessageSub);
    }
    UserMessageSubVo vo = BeanCopier.copy(userMessageSub, UserMessageSubVo.class);
    return vo;
  }  
  
  /**
   * 保存所有.
   *
   * @param userId the user id
   * @param tenantId the tenant id
   */
  public void saveOrUpdate(int userId, int tenantId)
  {    
    List<MessageModule> messageModules = MessageMetaManager.getInstance().getAllMessageModules();
    for (MessageModule messageModule : messageModules)
    {
      save(userId, tenantId, messageModule);
    }
  }
    
  public void saveOrUpdate(int userId, int tenantId, String moduleCode)
  {
    MessageModule messageModule = MessageMetaManager.getInstance().getMessageModule(moduleCode);
    save(userId, tenantId, messageModule);
  }

  /**
   * @param userId
   * @param tenantId
   * @param messageModule
   */
  private void save(int userId, int tenantId, MessageModule messageModule)
  {
    List<MessageMeta> messageMetas = messageModule.getMetas();
    for (MessageMeta messageMeta : messageMetas)
    {
      this.saveOrUpdate(userId, tenantId, messageModule.getCode(), messageMeta.getCode(), SaapConstants.MESSAGE_CHANNELS);
    }
  }
  
  @CacheEvict(value=CacheName.USER_MESSAGE_SUB, allEntries=true)
  public void delete(int userId, int tenantId)
  {    
    List<MessageModule> messageModules = MessageMetaManager.getInstance().getAllMessageModules();
    for (MessageModule messageModule : messageModules)
    {
      delete(userId, tenantId, messageModule);
    }
  }
  
//  System.out.println("12-45-23-bb-dd".matches("^[1-9]+[\\-]{1}[1-9]+[\\-]{1}[A-Za-z0-9|\\-]*"));
//  System.out.println("12-45-23-bb-dd".matches("^[1-9]+[\\-]{1}[1-9]+[\\-]{1}[A-Za-z0-9|\\-]+"));
//  System.out.println("12-45-23-44-55".matches("^[1-9]+[\\-]{1}[1-9]+[\\-]{1}[A-Za-z0-9|\\-]+"));
  @CacheEvict(value=CacheName.USER_MESSAGE_SUB, allEntries=true)
  public void delete(int userId, int tenantId, String moduleCode)
  {
    MessageModule messageModule = MessageMetaManager.getInstance().getMessageModule(moduleCode);
    this.delete(userId, tenantId, messageModule);
  }
  
  private void delete(int userId, int tenantId, MessageModule messageModule)
  {
    List<MessageMeta> messageMetas = messageModule.getMetas();
    for (MessageMeta messageMeta : messageMetas)
    {
      this.saveOrUpdate(userId, tenantId, messageModule.getCode(), messageMeta.getCode(), new String[]{});
    }
  }
  
  /* (non-Javadoc)
   * @see com.littcore.saap.message.service.impl.IUserMessageSubService#load(int, int, java.lang.String, java.lang.String)
   */
  @Override
  public UserMessageSub load(int userId, int tenantId, String moduleCode, String messageCode)
  {
    String hql = "from UserMessageSub where createBy=? and tenantId=? and moduleCode=? and messageCode=?";
    return userMessageSubDao.uniqueResult(hql, new Object[]{userId, tenantId, moduleCode, messageCode}, UserMessageSub.class);
  }
  
  /* (non-Javadoc)
   * @see com.littcore.saap.message.service.impl.IUserMessageSubService#find(int, int, java.lang.String, java.lang.String)
   */
  @Override
  //@Cacheable(value=CacheName.USER_MESSAGE_SUB, key="#userId+'-'+#tenantId+'-'+#moduleCode+'-'+#messageCode")
  public UserMessageSubVo find(int userId, int tenantId, String moduleCode, String messageCode)
  {
    UserMessageSub userMessageSub = this.load(userId, tenantId, moduleCode, messageCode);
    if(userMessageSub==null)
      return null;
    UserMessageSubVo vo = BeanCopier.copy(userMessageSub, UserMessageSubVo.class);
    return vo;
  }
  
  /* (non-Javadoc)
   * @see com.littcore.saap.message.service.impl.IUserMessageSubService#listByUser(int, int)
   */
  @Override
  public List<UserMessageSub> listByUser(int userId, int tenantId)
  {
    String hql = "from UserMessageSub where createBy=? and tenantId=?";
    return userMessageSubDao.listAll(hql, new Object[]{userId, tenantId});
  }

}
